import { defineComponent, ref, provide, inject, computed, watchEffect } from 'vue'
import type {
  addEditState,
  questionSideListState,
  showParamsState,
  RowState
} from '@/types/baseConfig'
import type { addParamState } from '@/types/form'
import type { PropType } from 'vue'
import { mergeParams, getRule, getQueryForm, queryFormTo, getRowValue } from '@/utils/dyForm'
import addEdit from '@/basic/addEdit/index'
import { useFullscreen } from '@vueuse/core'
import dyFormApi from '@/service/api/dyForm'
import { NModal, NButton, useMessage } from 'naive-ui'
import MacHeader from '@/components/codeBlock/MacHeader'
import pageStyle from './styles/edit.module.scss'
import YnForm from '@/components/yFormData/QuestionTypes/YnForm'
import YnFormItem from '@/components/yFormData/QuestionTypes/YnFormItem'
import DynamicComponent from '@/components/yFormData/QuestionTypes/index'
import { initFormState } from '@/types/baseConfig'

const RowChilder = defineComponent({
  props: {
    modelValue: {
      type: Array as PropType<questionSideListState[]>,
      default: () => []
    },
    queryForm: {
      type: Object,
      default: () => {
        return {}
      }
    },
    isRow: Boolean,
    row: {
      type: Object as PropType<RowState>,
      default: () => {
        return {}
      }
    }
  },
  emits: ['change'],
  setup(props: any, { emit }) {
    const $clone = inject('$clone') as <T>(data: T) => T

    const valChange = (e: questionSideListState) => {
      emit('change', e)
    }

    const draStyle = computed(() => {
      let style: any = {}
      if (props.isRow) {
        style.gridGap = `${props.row.yGap}px ${props.row.xGap}px`
        const arr = $clone(questions.value).map((el: any) => {
          return el.ColLayoutForm.width
        })
        style.gridTemplateColumns = arr.join(' ')
        const names = ['autoFlow', 'alignItems', 'justifyItems', 'alignContent', 'justifyContent']
        names.forEach((el: string) => {
          if (props.row[el]) {
            style[el] = props.row[el]
          }
        })
        if (props.row?.zdyStyle) {
          style = {
            ...style,
            ...props.row.zdyStyle
          }
        }
      }
      return style
    })
    const questions = ref<questionSideListState[]>([])
    watchEffect(() => {
      const list = props.modelValue
      questions.value = list.filter((el: questionSideListState) => {
        return props.queryForm?.id ? el.commonForm.editShow : el.commonForm.show
      })
    })
    return () => (
      <div class={`${props.isRow && 'row'}`} style={draStyle.value}>
        {questions.value.map((element: questionSideListState) => (
          <>
            {element.type === 'RowLayout' ? (
              <div class="zdy-row">
                {element.RowLayoutForm && (
                  <RowChilder
                    isRow
                    row={element.RowLayoutForm}
                    query-form={props.queryForm}
                    v-model={element.RowLayoutForm.childer}
                    onChange={valChange}
                  />
                )}
              </div>
            ) : (
              <>
                {element.formItem && (
                  <div class={`card ${props.isRow && 'card-grid'}`}>
                    <YnFormItem
                      {...element.formItem}
                      label={element.commonForm.labelName}
                      path={element.commonForm.labelKey}
                    >
                      <DynamicComponent
                        component={element.type}
                        comp-data={element}
                        onChange={valChange}
                      ></DynamicComponent>
                    </YnFormItem>
                  </div>
                )}
              </>
            )}
          </>
        ))}
      </div>
    )
  }
})
export default defineComponent({
  setup: function (props, { expose }) {
    const modalRef = ref()
    const { isFullscreen, toggle } = useFullscreen(modalRef)
    const $clone = inject('$clone') as <T>(data: T) => T

    /**
     *  提交表单
     * */
    const toast = useMessage()
    const formRef: any = ref(null)
    const saveRequest = async () => {
      const errors = await formRef.value.validate()
      if (!errors) {
        const params: any = queryFormTo(queryForm.value)
        console.log(params)
        toast.success(`验证通过, 模拟${isAddEdit ? '编辑' : '添加'}成功`)
      }
    }

    /**
     *  表单组件值发生改变
     * */
    const valChange = (e: questionSideListState) => {
      showParamsChange(questions.value, e)
    }

    const showParamsChange = (arr: questionSideListState[], e: questionSideListState) => {
      arr.map((el: questionSideListState) => {
        let status = false
        if (el.commonForm.showParams && el.commonForm.showParams.length > 0) {
          status = el.commonForm.showParams.some((item: showParamsState) => {
            return item.childer.some((element: addParamState) => {
              return (
                element.labelKey === e.commonForm.labelKey &&
                element.trigger.includes(queryForm.value.id ? 'edit' : 'add')
              )
            })
          })
        }
        if (!status) {
          if (el.type === 'RowLayout' && el.RowLayoutForm && el.RowLayoutForm.childer.length > 0) {
            showParamsChange(el.RowLayoutForm.childer, e)
          }
          return el
        }
        el.commonForm.show = el.commonForm.showParams.some((element: showParamsState) => {
          return element.childer.every((item: addParamState) => {
            const elVal = queryForm.value[item.labelKey]
            let isSuccess = false
            switch (item.way) {
              case 'noeqEmpty':
                isSuccess = elVal !== undefined && elVal !== null
                break
              case 'eq':
                isSuccess = elVal == item.value
                break
              case 'noeq':
                isSuccess = elVal != item.value
                break
              case 'gt':
                isSuccess = elVal > item.value
                break
              case 'lt':
                isSuccess = elVal < item.value
                break
              case 'includes':
                isSuccess = item.value.includes(elVal)
                break
              case 'noincludes':
                isSuccess = !item.value.includes(elVal)
                break
            }
            return isSuccess
          })
        })
        el.commonForm.editShow = el.commonForm.show
        if (!el.commonForm.show) {
          const oldValue = queryForm.value[el.commonForm.labelKey]
          if (oldValue !== null && oldValue !== undefined && oldValue !== '') {
            el.commonForm.defaultValue = null
            valChange(el)
          }
        }
        if (el.type === 'RowLayout' && el.RowLayoutForm && el.RowLayoutForm.childer.length > 0) {
          showParamsChange(el.RowLayoutForm.childer, e)
        }
        return el
      })
    }

    /**
     *  初始化展示隐藏
     * */
    const initShowParams = (arr: questionSideListState[]) => {
      arr.forEach((el: questionSideListState) => {
        if (el.type === 'RowLayout') {
          if (el.RowLayoutForm && el.RowLayoutForm.childer.length > 0) {
            initShowParams(el.RowLayoutForm.childer)
          }
        } else {
          valChange(el)
        }
      })
    }
    /**
     *  初始化默认值
     * */
    const queryForm: any = ref({})
    provide('queryForm', queryForm)

    /**
     *  初始化规则验证
     * */
    const rules: any = ref({})
    const ruleInit = () => {
      rules.value = getArrRule(questions.value)
    }
    const getArrRule = (arr: questionSideListState[]) => {
      let ruleInfo: any = {}
      arr.forEach((el: questionSideListState) => {
        if (el.type === 'RowLayout') {
          if (el.RowLayoutForm && el.RowLayoutForm.childer.length > 0) {
            const newRuleInfo = getArrRule(el.RowLayoutForm.childer)
            ruleInfo = mergeParams(ruleInfo, newRuleInfo)
          }
        } else {
          ruleInfo[el.commonForm.labelKey] = getRule(el, queryForm.value)
        }
      })
      return ruleInfo
    }
    /**
     *  初始化queryForm
     * */
    const initQueryForm = (
      questions: questionSideListState[],
      initForm: initFormState[],
      row: any
    ) => {
      const params = getQueryForm(questions)
      if (row && row?.id) {
        //  TODO 继承
        initForm.forEach((el: initFormState) => {
          if (['assembly', 'local'].includes(el.type)) {
            if (row) {
              const rowValue = getRowValue($clone(row), el.oldKey)
              params[el.newKey] = rowValue
            }
          } else {
            params[el.newKey] = el.oldKey
          }
        })
      }
      queryForm.value = params
    }

    /**
     *  打开 && 关闭弹框
     * */
    let isAddEdit = true
    const show = ref(false)
    const title = ref<string>('添加页面')
    const diaWidth = ref('500')
    const info = ref<addEditState>(addEdit)
    const questions = ref<questionSideListState[]>([])
    const open = async (id: number, extend?: { row?: any; navTitle?: string }) => {
      const { data } = await dyFormApi.detail(id)
      data.addEdit = JSON.parse(data.addEdit)
      const itRow: addEditState = $clone(data.addEdit)
      diaWidth.value = itRow.basic.diaWidth || '500px'
      isAddEdit = false
      title.value = '添加'
      if (extend) {
        if (extend?.row && extend.row?.id) {
          isAddEdit = true
          title.value = '编辑'
        }
        if (extend?.navTitle) {
          title.value = extend.navTitle
        }
      }
      questions.value = itRow.questions
      initQueryForm(itRow.questions, itRow?.initForm || [], extend?.row || {})
      ruleInit()
      info.value = itRow
      initShowParams(questions.value)
      show.value = true
    }

    const close = () => {
      show.value = false
    }

    expose({
      open
    })
    return () => (
      <NModal show={show.value} onUpdateShow={close}>
        <div class={pageStyle.EditForm} ref={modalRef} style={{ width: diaWidth.value }}>
          <MacHeader
            title={title.value}
            is-fullscreen={isFullscreen.value}
            showDesc={false}
            onToggle={toggle}
            onClose={close}
          />
          <div class="content">
            <YnForm ref={formRef} {...info.value.basic} model={queryForm.value} rules={rules.value}>
              <RowChilder
                v-model:queryForm={queryForm.value}
                v-model={questions.value}
                onChange={valChange}
              />
            </YnForm>
            <div class="mt-[60px] flex items-center justify-end">
              <NButton type="primary" onClick={saveRequest}>
                <span>保存</span>
              </NButton>
            </div>
          </div>
        </div>
      </NModal>
    )
  }
})
